﻿using Microsoft.AspNetCore.Http;

using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

namespace zijian666.WebApi.Default
{
    /// <summary>
    /// 可跟踪的<seealso cref="HttpClient"/>
    /// </summary>
    public class TracingHttpMessageHandler : DelegatingHandler
    {
        /// <summary>
        /// 请求上下文访问器
        /// </summary>
        protected HttpContextAccessor HttpContextAccessor { get; }

        /// <summary>
        /// 默认构造函数
        /// </summary>
        /// <param name="httpContextAccessor"></param>
        public TracingHttpMessageHandler(HttpContextAccessor httpContextAccessor) => HttpContextAccessor = httpContextAccessor;

        /// <summary>
        /// 在请求中插入头 X-Correlation-ID
        /// </summary>
        /// <param name="request"></param>
        private void AppendTraceId(HttpRequestMessage request)
        {
            if (request.Headers is HttpRequestHeaders headers && HttpContextAccessor.HttpContext is HttpContext httpContext)
            {
                if (!headers.Contains("X-Correlation-ID") && !headers.Contains("X-Request-ID"))
                {
                    headers.Add("X-Correlation-ID", httpContext.TraceIdentifier);
                }
            }
        }


        /// <inheritdoc/>
        protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            AppendTraceId(request);
            return base.Send(request, cancellationToken);
        }

        /// <inheritdoc/>
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            AppendTraceId(request);
            return base.SendAsync(request, cancellationToken);
        }
    }
}
